﻿Option Strict On

Imports System.ComponentModel

Public Class GridExtPL
    Implements IReloadCommand, ISaveCommand, INewCommand

    Private _gridReloadState As GridExtPLState


    Public Property Dataset As DataSet Implements ISaveCommand.Dataset
    Public WithEvents MetaDataTable As CommonExt.MetaDataTable
    Public WithEvents DetailView As Views.Grid.GridView

    'Use to know what index we are working on
    Public DetailViewIndex As Integer
    Public vEdit As VEdit

    '''<remarks>
    '''When you define "Event ValidateMasterRow" VB.NET automatically adds a field call ValidateMasterRowEvent.
    '''The "ValidateMasterRowEvent" will not show up in the IDE or Intellisense,
    '''however you are free to use it in your code
    '''
    ''' Follow the code to ...GridView1_ValidateRow to see 
    ''' the code using ValidateMasterRowEvent.
    ''' 
    ''' Also in the consumer of GridExtPl an "Addhandler" must be assigned to the event so that ValidateMasterRowEvent value can be different than NOTHING
    ''' EX: WidgetExplorer.vb line XX        ' AddHandler aGridControl.ValidateMasterRow, AddressOf WidgetCase.ValidateMasterRow
    '''</remarks>
    ''' 
    Public Event ValidateMasterRow(ByVal sender As Object, ByVal e As ValidateRowEventArgs)
    Public Event AfterSave()

    ''' <summary>
    ''' This event is use to continue to customize a view by code from our xxxxCase.vb file
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="gridView"></param>
    ''' <remarks>Ex: gridView.Columns("pOrder").SortOrder = DevExpress.Data.ColumnSortOrder.Ascending   </remarks>
    Public Event AfterInitView(ByVal sender As Object, ByVal gridView As GridView)

    ''' <summary>
    ''' This event is use to add key shortcut in our xxxxCase.vb file
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Call after GridControl.ProcessGridKey</remarks>
    Public Event AfterProcessGridKey(ByVal sender As Object, ByVal e As KeyEventArgs)
    ''' <summary>
    ''' This event is use to Allow Drop on our Control, from our xxxxCase.vb file 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Call from GridControl.DragDrop / GridControl.AllowDrop must be Set to True use the AfterInitView to do so</remarks>
    Public Event DragDropExt(ByVal sender As Object, ByVal e As DragEventArgs)
    ''' <summary>
    ''' This event is use to Allow DragOver on our Control, from our xxxxCase.vb file 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Call from GridControl.DragOver / GridControl.AllowDrop must be Set to True use the AfterInitView to do so</remarks>
    Public Event DragOverExt(ByVal sender As Object, ByVal e As DragEventArgs)
    ''' <summary>
    ''' This event is use to customize mouse action on our Control, from our xxxxCase.vb file 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Call from DetailView.MouseMove </remarks>
    Public Event DetailMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
    ''' <summary>
    ''' This event is use to customize mouse button action on our Control, from our xxxxCase.vb file 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Call from DetailView.MouseDown </remarks>
    Public Event DetailMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)

    Public Event ValidateDetailRow(ByVal sender As Object, ByVal e As ValidateRowEventArgs)

    Public Event InitNewMasterRow(ByVal sender As Object, ByVal e As InitNewRowEventArgs)
    Public Event InitNewDetailRow(ByVal sender As Object, ByVal e As InitNewRowEventArgs)

    Public Event ShownMasterEditor(ByVal sender As Object, ByVal e As EventArgs)
    Public Event ShownDetailEditor(ByVal sender As Object, ByVal e As EventArgs)

    Public Event HiddenMasterEditor(ByVal sender As Object, ByVal e As EventArgs)
    Public Event HiddenDetailEditor(ByVal sender As Object, ByVal e As EventArgs)

    Public Event InitGridActionOptionList(ByVal sender As Object, ByVal e As EventArgs)

    Public Event ProcessCurrentMasterRecord(ByVal sender As Object, e As ValidateRowEventArgs)
    Public Event ProcessCurrentDetailRecord(ByVal sender As Object, e As ValidateRowEventArgs, ByVal index As Integer)

    Public Event DeleteRow(ByVal row As DataRow, ByVal e As CancelEventArgs)

    Public Event MasterCellValueChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs)
    Public Event DetailCellValueChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs)

    Public Event MasterCustomColumnDisplayText(ByVal sender As Object, ByVal e As CustomColumnDisplayTextEventArgs)
    Public Event DetailCustomColumnDisplayText(ByVal sender As Object, ByVal e As CustomColumnDisplayTextEventArgs)

    Public Event MasterRowCellStyle(ByVal sender As Object, ByVal e As RowCellStyleEventArgs)
    Public Event DetailRowCellStyle(ByVal sender As Object, ByVal e As RowCellStyleEventArgs)

    Public Event MasterRowStyle(ByVal sender As Object, e As DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs)
    Public Event DetailRowStyle(ByVal sender As Object, e As DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs)

    Public Event MasterCustomRowCellEditForEditing(ByVal sender As System.Object, ByVal e As DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs)
    Public Event DetailCustomRowCellEditForEditing(ByVal sender As System.Object, ByVal e As DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs)

    Public Event DetailRowClick(ByVal sender As Object, ByVal e As RowClickEventArgs)
    Public Event MasterRowClick(ByVal sender As Object, ByVal e As RowClickEventArgs)

    Public Event MasterRowNotify(sender As Object, e As DevExpress.XtraGrid.Views.Base.RowObjectEventArgs)
    Public Event DetailRowNotify(sender As Object, e As DevExpress.XtraGrid.Views.Base.RowObjectEventArgs)

    Public Event AfterViewRegistered(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.ViewOperationEventArgs)
    Public Event AfterLoad(ByVal sender As Object, ByVal e As System.EventArgs)

    Public Event MainContextMenuBeforePopup(ByVal sender As Object, ByVal e As System.EventArgs)
    Public Event DetailContextMenuBeforePopup(ByVal sender As Object, ByVal e As System.EventArgs)


    Private TimeEdit As RepositoryItemTimeEdit
    Private CalcEdit As RepositoryItemCalcEdit
    Private MemoEdit As RepositoryItemMemoEdit
    Private RichTextEdit As RepositoryItemRichTextEdit


    Private formatType As DevExpress.Utils.FormatType

    Public editorView As DataView
    Public AllowCreate As Boolean
    Public AllowRead As Boolean
    Public AllowUpdate As Boolean
    Public AllowDelete As Boolean

    Public DetailAccess As MetaQueryAccess = Nothing
    Public FormCtrlCD As String
    Public Property CtrlName As String Implements IReloadCommand.CtrlName

    ''' <summary>
    ''' Use flag to determines if the grid should loads with or without his child's queries.
    ''' </summary>
    ''' <remarks>
    ''' Ex.: ItemMasterControl.vb line 217 - we want to show Site's info but not his child query like SiteSection. 
    ''' For now, this takes over the Security since the developper set this property manually.
    ''' Boolean: True by Default
    ''' </remarks>
    Public LoadWithChilds As Boolean = True

    'Pour le backgoudWorker - aleblanc - 2011-09-06
    'Reste les LOV a faire... 
    'Private waitWindow As DevExpress.Utils.WaitDialogForm
    'Private WithEvents bgWorker As System.ComponentModel.BackgroundWorker

#Region "Constructor"
    Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()
        GridControl1.ForceInitialize()
        AddHandler GridControl1.EmbeddedNavigator.ButtonClick, AddressOf GridControl1_EmbeddedNavigator_ButtonClick
        '
        AllowCreate = True
        AllowRead = True
        AllowUpdate = True
        AllowDelete = True
        '
        TimeEdit = New RepositoryItemTimeEdit()
        CalcEdit = New RepositoryItemCalcEdit()
        MemoEdit = New RepositoryItemMemoEdit()
        MemoEdit.WordWrap = True


        RichTextEdit = New RepositoryItemRichTextEdit()
        RichTextEdit.AllowHtmlDraw = DevExpress.Utils.DefaultBoolean.True
        RichTextEdit.DocumentFormat = DevExpress.XtraRichEdit.DocumentFormat.Rtf
        RichTextEdit.OptionsExport.Html.EmbedImages = True
        RichTextEdit.MaxHeight = 50

        'OutStandingIssue: Voir ce que ca donne sur un PC Danois..
        RichTextEdit.OptionsImport.Html.AutoDetectEncoding = True

        Me.GridControl1.RepositoryItems.Add(TimeEdit)
        Me.GridControl1.RepositoryItems.Add(CalcEdit)
        Me.GridControl1.RepositoryItems.Add(MemoEdit)
        Me.GridControl1.RepositoryItems.Add(RichTextEdit)

        Dataset = New DataSet("GridExtPL")
        ' Add any initialization after the InitializeComponent() call.
        InitActionOption()

        ' Pour le backgoudWorker - aleblanc - 2011-09-06
        'bgWorker = New System.ComponentModel.BackgroundWorker()
        'bgWorker.WorkerReportsProgress = False
        'bgWorker.WorkerSupportsCancellation = False
    End Sub

    'Public Sub New(ByVal aQueryName As String)
    '    Me.New()
    '    MainQueryName = aQueryName
    '    ' Add any initialization after the InitializeComponent() call.
    '    InitGridExt()
    'End Sub

#End Region

#Region " Properties"
    ''' <summary>
    ''' This property give the parent datarow of a detail grid
    ''' </summary>
    ''' <value>DataRow</value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ParentSelectedDataRow() As DataRow
        Get
            Dim view As Views.Grid.GridView = CType(GridControl1.FocusedView.ParentView, Views.Grid.GridView)
            Return view.GetFocusedDataRow
        End Get
    End Property

    Public Property Pl() As PL.PLBase

    Public Property GridActionOptionList() As CommonExt.Base.ActionOptionList

    Public Property DefaultActionOptionList() As CommonExt.Base.ActionOptionList

    Public Property GridContextMenu() As GridViewMenu

    Public Property MainQueryName() As String
#End Region
    ''' <summary>
    ''' Use to Flag if displayed columns are according to the security profile
    ''' Default value is False for Preview Screen in metacommand... to be changed soon B.Desjardins Outstanding
    ''' </summary>
    ''' <returns>Boolean: False by Default</returns>
    ''' <remarks></remarks>
    Public Property SecureGrid() As Boolean = False

    ''' <summary>
    ''' Property to automaticly open the first Master Row in the grid
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property ExpandFirstMasterRow() As Boolean = False

    ' Pour le backgoudWorker - aleblanc - 2011-09-06
    'Private Sub bgWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgWorker.DoWork
    '    Dim withchild As Boolean = CBool(e.Argument)
    '    If Pl IsNot Nothing Then
    '        Pl.InitData(withChild)
    '    Else
    '        RaiseEvent InitDataExt(Me, withchild) ' This event can be used to bypass the use of a Processing Layer object(PL)
    '    End If
    'End Sub

    ' Pour le backgoudWorker - aleblanc - 2011-09-06
    'Private Sub bgWorker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgWorker.RunWorkerCompleted
    '    Me.Dataset = Pl.Dataset
    '    InitGrid()
    '    waitWindow.Close()
    'End Sub

    Public Sub InitGridExt(Optional ByVal withChild As Boolean = True)
        Dim mainViewAccess As MetaQueryAccess = Nothing
        Dim mqCtrlCode As String = Nothing
        ' Pour le backgoudWorker - aleblanc - 2011-09-06
        'If Not bgWorker.IsBusy Then
        '    waitWindow = New DevExpress.Utils.WaitDialogForm("Un Instant svp", "Chargement des données...")
        '    waitWindow.LookAndFeel.SkinName = "Blue"
        '    waitWindow.LookAndFeel.Style = DevExpress.LookAndFeel.LookAndFeelStyle.Skin
        '    waitWindow.LookAndFeel.UseDefaultLookAndFeel = False
        '    waitWindow.LookAndFeel.UseWindowsXPTheme = False
        '    bgWorker.RunWorkerAsync(withChild)
        'End If
        GridControl1.BeginUpdate()
        If Not String.IsNullOrWhiteSpace(FormCtrlCD) Then
            'by design we restrict all access , BD
            Me.CtrlName = FormCtrlCD
            Me.AllowRead = False
            Me.AllowUpdate = False
            Me.AllowDelete = False
            Me.AllowCreate = False
            If Pl IsNot Nothing Then
                'Testpoint-0001: Here test if the Queryname match it's control Name 'Case sensitive'
                mqCtrlCode = AppManager.GetControlMqFromForm(FormCtrlCD, Pl.QueryName)
                'mqCtrlCode = AppManager.GetControlSecurity(, "METAQ")
                If Not String.IsNullOrWhiteSpace(mqCtrlCode) Then
                    mainViewAccess = New MetaQueryAccess(mqCtrlCode)
                    Me.AllowRead = CBool(CShort(mainViewAccess.AllowRead))
                    Me.AllowUpdate = mainViewAccess.AllowUpdate
                    Me.AllowDelete = mainViewAccess.AllowDelete
                    Me.AllowCreate = mainViewAccess.AllowCreate
                End If
            Else
                MessageWindow.ShowMessage("PL process layer not set", MsgBoxStyle.Exclamation)
            End If
        End If
        If AllowRead Then
            If Pl IsNot Nothing Then
                Pl.InitData(withChild)
                Me.Dataset = Pl.Dataset
            End If
        End If
        'we do a initgrid to show the user a grid empty
        InitGrid()
        GridControl1.EndUpdate()
        Dim i As Integer = GridView1.FocusedRowHandle
        'Open the first masterow
        'If we put in between the endupdate it's  missing a refresh
        'we test again the allowread because if false the metaDataTable is nothing and a call on it is not possible
        If AllowRead Then
            If ExpandFirstMasterRow AndAlso MetaDataTable.Rows.Count > 0 Then
                GridView1.ExpandMasterRow(i)
            End If
        End If
    End Sub

    'Basé sur l'exemple de http://www.devexpress.com/Support/Center/e/E1127.aspx
    Private Sub GridControl1_EmbeddedNavigator_ButtonClick(ByVal sender As Object, ByVal e As NavigatorButtonClickEventArgs)
        If e.Button.ButtonType = NavigatorButtonType.Remove Then
            DeleteCurrentRows()
            'TestPoint: Si on enleve cette ligne ca continue l'événement et va delete l'autre ligne en focus (2 lignes) - aleblanc 2011-10-07.
            e.Handled = True
        End If
    End Sub
    ''' <summary>
    ''' This Sub initialise the GridExt 
    ''' </summary>
    ''' <remarks>La grille essaye toujours d'avoir les enfants (by design)
    ''' a) creates a Dataset , the Table(0) is the Parent
    ''' b) </remarks>
    Private Sub InitGrid()
        Dim metaDt As MetaDataTable
        Dim relationName As String
        Dim parentRelation As String
        Dim queryName As String
        Dim level As Integer
        '
        Try
            GridControl1.LevelTree.Nodes.Clear()

            If Dataset IsNot Nothing AndAlso Dataset.Tables.Count > 0 Then
                MainQueryName = Dataset.Tables(0).TableName
                'Ici on se sert du parent de notre dataset
                'Par convention la table 0 de notre DataSet est le parent de nos relation
                MetaDataTable = CType(Dataset.Tables(0), MetaDataTable)
                GridControl1.DataSource = Dataset.Tables(0)
                InitMainView()
                'Ici on parcours les tables a afficher
                If LoadWithChilds Then
                    For Each row As DataRow In MetaDataTable.MetaCommand.GetChildDisplayQuery.Rows
                        If CInt(row("RelationOrder")) >= 0 Then
                            metaDt = CType(Dataset.Tables(row("QueryName").ToString), MetaDataTable)
                            parentRelation = row("ParentRelation").ToString
                            relationName = row("Relation").ToString
                            queryName = row("Relation").ToString
                            level = CInt(row("MetaqueryLevel"))
                            InitAndLinkDetailViewProperty(parentRelation, relationName, metaDt, level)
                        End If
                    Next
                End If
            End If
        Catch ex As Exception
            MessageWindow.ShowMessage(ex, MsgBoxStyle.Information)
        End Try
    End Sub


    Private Sub InitAndLinkDetailViewProperty(ByVal parentRelation As String, ByVal relationName As String, ByVal table As MetaDataTable, ByVal level As Integer)
        Dim aDetailView As GridView = New GridView(GridControl1)
        Dim column As GridColumn
        Dim colVisible As Integer
        Dim grdLvLNode As GridLevelNode
        Dim tmpLvLNode As GridLevelNode
        Dim tableColumns As DataTable
        Dim columnSortInfo As List(Of GridColumnSortInfo) = New List(Of GridColumnSortInfo)
        Dim columnSortMode As List(Of ColumnSortMode) = New List(Of ColumnSortMode)
        Dim applySort As Boolean = False
        Dim colname As String
        '
        Dim aColumnIsVisible As Boolean
        '
        aDetailView.Name = relationName
        If level = 1 Then
            GridControl1.LevelTree.Nodes.Add(relationName, aDetailView)
        Else
            If GridControl1.LevelTree.Nodes.Contains(parentRelation) Then
                'GridControl1.LevelTree.Nodes(parentRelation).Nodes.Add(relationName, aDetailView)
                grdLvLNode = GridControl1.LevelTree.Nodes.Item(parentRelation)
                tmpLvLNode = grdLvLNode.Nodes.Add(relationName, aDetailView)
            End If
        End If
        '
        ' On le force a false car quand on a des cellule de mergé le Row Selector disparait
        aDetailView.OptionsView.AllowCellMerge = False
        aDetailView.OptionsView.ShowFooter = False
        'Le tag est utilisé pour se retrouvé dans dans les événements plus loin
        'ByDesign c'est le nom de la metaquery.
        aDetailView.Tag = table.TableName
        aDetailView.PopulateColumns(table)
        aDetailView.Columns.Clear()
        '
        '
        'Ici on CTYPE relation.ChildTable car un DataRelation (un type du Framework de MS) contient des DataTable, 
        'comme notre MetaDataTable hérite d'un DataTable il est compatible

        If SecureGrid Then
            tableColumns = CommonExt.Base.AppManager.GetUserColumnSecurity(table.TableName, CommonExt.Base.AppManager.UserID)
        Else
            tableColumns = table.MetaData
        End If

        tableColumns.TableName = table.TableName

        For Each arow As DataRow In tableColumns.Rows
            colname = arow("ColumnName").ToString
            '
            colVisible = CInt(arow("pVisible"))
            Select Case colVisible
                Case 0 'On cache la colonne
                    aColumnIsVisible = False
                Case 1 'On affiche la colonne
                    aColumnIsVisible = True
                Case 2 'On affiche la colonne selon le profile du user
                    aColumnIsVisible = False
                    If AppManager.ApplicationOption.DescriptionColumnIndex = 3 Then   'L'usager a choisi ALT
                        If colname.EndsWith("_ALT") Then
                            aColumnIsVisible = True
                        End If
                    Else 'L'usager a choisi PRM
                        If colname.EndsWith("_PRM") Then
                            aColumnIsVisible = True
                        End If
                    End If
                Case Else
                    aColumnIsVisible = False
            End Select
            '
            If colVisible <> 3 Then
                column = aDetailView.Columns.AddField(colname)
                If column IsNot Nothing Then
                    column.VisibleIndex = CInt(arow("pOrder"))
                    column.Caption = arow("pCaption").ToString
                    column.Visible = aColumnIsVisible
                    column.Width = CInt(arow("pWidth"))
                    'column.OptionsColumn.AllowEdit = Not CBool(arow("pLocked"))
                    column.OptionsColumn.ReadOnly = CBool(arow("pLocked"))

                    If Not String.IsNullOrEmpty(Trim(arow("pBackColor").ToString)) Then
                        column.AppearanceCell.BackColor = ColorTranslator.FromOle(Math.Abs(CInt(arow("pBackColor"))))
                    End If

                    If CBool(arow("pMerge")) Then
                        aDetailView.OptionsView.AllowCellMerge = True
                        column.OptionsColumn.AllowMerge = DevExpress.Utils.DefaultBoolean.True
                    Else
                        column.OptionsColumn.AllowMerge = DevExpress.Utils.DefaultBoolean.False
                    End If
                    '
                    If CInt(arow("pGroupByOrder")) >= 0 Then
                        column.GroupIndex = CInt(arow("pGroupByOrder"))
                    End If
                    '
                    column.ToolTip = arow("pToolTip").ToString
                    '
                    formatType = DevExGridHelper.GetFormatType(arow)
                    If formatType = DevExpress.Utils.FormatType.DateTime Then
                        TimeEdit.DisplayFormat.FormatType = formatType
                        TimeEdit.DisplayFormat.FormatString = arow("pNumberFormat").ToString
                        TimeEdit.EditFormat.FormatType = formatType
                        TimeEdit.EditFormat.FormatString = arow("pNumberFormat").ToString
                        TimeEdit.EditMask = arow("pNumberFormat").ToString
                        TimeEdit.Mask.AutoComplete = Mask.AutoCompleteType.None
                        TimeEdit.AllowMouseWheel = True
                        column.ColumnEdit = TimeEdit
                    End If
                    '
                    If formatType = DevExpress.Utils.FormatType.Numeric Then
                        CalcEdit.EditFormat.FormatType = DevExpress.Utils.FormatType.Numeric
                        CalcEdit.EditFormat.FormatString = arow("pNumberFormat").ToString()
                        CalcEdit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric
                        CalcEdit.DisplayFormat.FormatString = arow("pNumberFormat").ToString()
                        column.ColumnEdit = CalcEdit
                    End If
                    '
                    If Not IsDBNull(arow("pNumberFormatID_FK")) Then
                        If CType(arow("pNumberFormatID_FK"), Guid) = IdRepository.META_NUMBERFORMAT_EXTERNALEDITOR Then
                            Select Case arow("pNumberFormat").ToString
                                Case "RichText"
                                    column.ColumnEdit = RichTextEdit
                                Case ("Memo")
                                    column.ColumnEdit = MemoEdit
                            End Select
                        End If
                    End If
                    '
                    column.DisplayFormat.FormatType = formatType
                    column.DisplayFormat.FormatString = arow("pNumberFormat").ToString
                    '
                    If Not IsDBNull(arow("pSortByOrder")) AndAlso CInt(arow("pSortByOrder")) >= 0 Then
                        applySort = True
                    End If

                    column.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.None
                    DevExGridHelper.AssignCustomSummaryProperties(aDetailView, column, arow)
                End If
            End If
        Next

        If applySort Then
            Dim aSort As DataTable
            aSort = (From oControl In tableColumns.AsEnumerable _
                     Where oControl.Field(Of Integer?)("pSortByOrder") >= 0 _
                     Order By oControl.Field(Of Integer)("pSortByOrder") Ascending
                     Select oControl).CopyToDataTable()

            Dim aSortGuid As System.Guid
            For Each aRow As DataRow In aSort.Rows
                If Guid.TryParse(aRow("pSortOrderID_FK").ToString, aSortGuid) Then
                    'By design we sort Ascending  
                    Select Case CType(aRow("pSortOrderID_FK"), Guid)
                        Case IdRepository.APP_COLUMNSORTORDER_DESCENDING
                            columnSortInfo.Add(New GridColumnSortInfo(aDetailView.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.Descending))

                        Case IdRepository.APP_COLUMNSORTORDER_NONE
                            columnSortInfo.Add(New GridColumnSortInfo(aDetailView.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.None))

                        Case Else
                            columnSortInfo.Add(New GridColumnSortInfo(aDetailView.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.Ascending))
                    End Select
                Else
                    columnSortInfo.Add(New GridColumnSortInfo(aDetailView.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.Ascending))

                End If
                aDetailView.Columns(aRow("ColumnName").ToString).SortMode = DevExpress.XtraGrid.ColumnSortMode.DisplayText
                aDetailView.Columns(aRow("ColumnName").ToString).SortIndex = CInt(aRow("pSortByOrder"))
            Next
        End If
        '
        'OUSTANDINGISSUE: ClearAndAddRange() écrase ce qui fut configurer pour le pGroupByOrder a la ligne 444. clieng 2013-04-12.
        '    aDetailView.SortInfo.ClearAndAddRange(columnSortInfo.ToArray(), 0)
        '
        'Grid Display parameters
        'This could all be define in Metacontrol Props
        aDetailView.HorzScrollVisibility = Views.Base.ScrollVisibility.Always
        aDetailView.OptionsDetail.EnableDetailToolTip = True
        aDetailView.OptionsDetail.AllowExpandEmptyDetails = True
        '
        aDetailView.OptionsFilter.DefaultFilterEditorView = FilterEditorViewMode.VisualAndText
        aDetailView.OptionsFilter.ShowAllTableValuesInFilterPopup = True
        aDetailView.OptionsFilter.UseNewCustomFilterDialog = True
        '
        aDetailView.OptionsView.ColumnAutoWidth = False
        aDetailView.OptionsView.NewItemRowPosition = NewItemRowPosition.Top
        aDetailView.OptionsView.ShowAutoFilterRow = True
        aDetailView.OptionsView.ShowChildrenInGroupPanel = True
        aDetailView.OptionsView.ShowFilterPanelMode = Views.Base.ShowFilterPanelMode.ShowAlways
        '
        'Le nom de l'onglet de la vue
        'aView.OptionsView.ShowViewCaption = True 'Permet d'afficher le nom du Caption dans une ligne en haut du Grid
        aDetailView.ViewCaption = table.MetaCommand.Caption

        'Necessaire pour les memoedit
        aDetailView.OptionsView.RowAutoHeight = True

        aDetailView.OptionsSelection.MultiSelect = True
        aDetailView.OptionsBehavior.EditorShowMode = DevExpress.Utils.EditorShowMode.MouseUp

        ''Make sure that the columns are define in the view before assignning LOV'S
        DevExGridHelper.AssignLKP(aDetailView, table, Me.GridControl1)
        RaiseEvent AfterInitView(Me, aDetailView)
        tableColumns.Dispose()
    End Sub
    ''' <summary>
    ''' Initialise la grille parents
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub InitMainView()
        Dim colVisible As Integer
        Dim mainView As Views.Base.ColumnView = CType(GridControl1.MainView, Views.Base.ColumnView)
        Dim column As DevExpress.XtraGrid.Columns.GridColumn
        Dim tableColumns As DataTable
        Dim colname As String
        Dim aColumnIsVisible As Boolean
        Dim columnSortInfo As List(Of GridColumnSortInfo) = New List(Of GridColumnSortInfo)
        Dim applySort As Boolean = False
        'This action is mandaotry due to the fact that as soon as Grid control datasource is set
        'the columns view are loaded but not specified the application requires
        GridView1.BeginDataUpdate()
        mainView.Columns.Clear()
        ' On le force a false car quand on a des cellule de mergé le Row Selector disparait
        GridView1.OptionsView.AllowCellMerge = False
        '
        If SecureGrid Then
            tableColumns = CommonExt.Base.AppManager.GetUserColumnSecurity(MetaDataTable.TableName, CommonExt.Base.AppManager.UserID)
        Else
            tableColumns = MetaDataTable.MetaData
        End If
        '
        Me.MetaDataTable.DefaultView.AllowEdit = Me.AllowUpdate
        Me.MetaDataTable.DefaultView.AllowDelete = Me.AllowDelete
        Me.MetaDataTable.DefaultView.AllowNew = Me.AllowCreate
        '
        For Each arow As DataRow In tableColumns.Rows
            colVisible = CInt(arow("pVisible"))
            colname = arow("ColumnName").ToString
            Select Case colVisible
                Case 0 'On cache la colonne
                    aColumnIsVisible = False
                Case 1 'On affiche la colonne
                    aColumnIsVisible = True
                Case 2 'On affiche la colonne selon le profile du user
                    aColumnIsVisible = False
                    If AppManager.ApplicationOption.DescriptionColumnIndex = 3 Then   'L'usager a choisi ALT
                        If colname.EndsWith("_ALT") Then
                            aColumnIsVisible = True
                        End If
                    Else 'L'usager a choisi PRM
                        If colname.EndsWith("_PRM") Then
                            aColumnIsVisible = True
                        End If
                    End If
                Case Else
                    aColumnIsVisible = False
            End Select
            '
            If colVisible <> 3 Then
                column = mainView.Columns.AddField(colname)
                column.VisibleIndex = CInt(arow("pOrder"))
                column.Caption = arow("pCaption").ToString
                column.Visible = aColumnIsVisible
                column.Width = CInt(arow("pWidth"))
                'column.OptionsColumn.AllowEdit = Not CBool(arow("pLocked"))
                column.OptionsColumn.ReadOnly = CBool(arow("pLocked"))
                column.ToolTip = arow("pToolTip").ToString

                If Not String.IsNullOrEmpty(Trim(arow("pBackColor").ToString)) Then
                    column.AppearanceCell.BackColor = ColorTranslator.FromOle(Math.Abs(CInt(arow("pBackColor"))))
                End If

                If CBool(arow("pMerge")) Then
                    GridView1.OptionsView.AllowCellMerge = True
                    column.OptionsColumn.AllowMerge = DevExpress.Utils.DefaultBoolean.True
                Else
                    column.OptionsColumn.AllowMerge = DevExpress.Utils.DefaultBoolean.False
                End If



                If CInt(arow("pGroupByOrder")) >= 0 Then
                    column.GroupIndex = CInt(arow("pGroupByOrder"))
                End If

                '
                formatType = DevExGridHelper.GetFormatType(arow)
                If formatType = DevExpress.Utils.FormatType.DateTime Then
                    TimeEdit.DisplayFormat.FormatType = formatType
                    TimeEdit.DisplayFormat.FormatString = arow("pNumberFormat").ToString
                    TimeEdit.EditFormat.FormatType = formatType
                    TimeEdit.EditFormat.FormatString = arow("pNumberFormat").ToString
                    TimeEdit.EditMask = arow("pNumberFormat").ToString

                    TimeEdit.Mask.AutoComplete = Mask.AutoCompleteType.None
                    TimeEdit.AllowMouseWheel = True

                    column.ColumnEdit = TimeEdit
                End If
                '
                If formatType = DevExpress.Utils.FormatType.Numeric Then
                    CalcEdit.EditFormat.FormatType = DevExpress.Utils.FormatType.Numeric
                    CalcEdit.EditFormat.FormatString = arow("pNumberFormat").ToString()
                    CalcEdit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric
                    CalcEdit.DisplayFormat.FormatString = arow("pNumberFormat").ToString()
                    column.ColumnEdit = CalcEdit
                End If
                '
                If Not IsDBNull(arow("pNumberFormatID_FK")) Then
                    If CType(arow("pNumberFormatID_FK"), Guid) = IdRepository.META_NUMBERFORMAT_EXTERNALEDITOR Then
                        Select Case arow("pNumberFormat").ToString
                            Case "RichText"
                                column.ColumnEdit = RichTextEdit
                            Case ("Memo")
                                column.ColumnEdit = MemoEdit
                        End Select
                    End If
                End If
                '
                If Not IsDBNull(arow("pSortByOrder")) AndAlso CInt(arow("pSortByOrder")) >= 0 Then
                    applySort = True
                End If
                '
                column.DisplayFormat.FormatType = formatType
                column.DisplayFormat.FormatString = arow("pNumberFormat").ToString
                '
                DevExGridHelper.AssignCustomSummaryProperties(GridView1, column, arow)
            End If
        Next

        If applySort Then
            Dim aSort As DataTable
            aSort = (From oControl In tableColumns.AsEnumerable _
                     Where oControl.Field(Of Integer?)("pSortByOrder") >= 0 _
                     Order By oControl.Field(Of Integer)("pSortByOrder") Ascending
                     Select oControl).CopyToDataTable()

            Dim aSortGuid As System.Guid
            For Each aRow As DataRow In aSort.Rows
                If Guid.TryParse(aRow("pSortOrderID_FK").ToString, aSortGuid) Then
                    'By design we sort Ascending  
                    Select Case aSortGuid
                        Case IdRepository.APP_COLUMNSORTORDER_DESCENDING
                            columnSortInfo.Add(New GridColumnSortInfo(GridView1.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.Descending))

                        Case IdRepository.APP_COLUMNSORTORDER_NONE
                            columnSortInfo.Add(New GridColumnSortInfo(GridView1.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.None))

                        Case Else
                            columnSortInfo.Add(New GridColumnSortInfo(GridView1.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.Ascending))

                    End Select
                Else
                    columnSortInfo.Add(New GridColumnSortInfo(GridView1.Columns(aRow("ColumnName").ToString), DevExpress.Data.ColumnSortOrder.Ascending))
                End If
                GridView1.Columns(aRow("ColumnName").ToString).SortMode = ColumnSortMode.DisplayText
                GridView1.Columns(aRow("ColumnName").ToString).SortIndex = CInt(aRow("pSortByOrder"))

            Next

        End If
        '
        GridView1.SortInfo.ClearAndAddRange(columnSortInfo.ToArray(), 0)
        '
        GridView1.EndDataUpdate()
        GridView1.GridControl = Me.GridControl1
        GridView1.Name = "ParentView"
        GridView1.Tag = MetaDataTable.TableName
        GridView1.HorzScrollVisibility = Views.Base.ScrollVisibility.Always
        '
        GridView1.OptionsDetail.AllowExpandEmptyDetails = True
        GridView1.OptionsDetail.EnableDetailToolTip = True
        '
        GridView1.OptionsFilter.DefaultFilterEditorView = FilterEditorViewMode.VisualAndText
        GridView1.OptionsFilter.ShowAllTableValuesInFilterPopup = True
        GridView1.OptionsFilter.UseNewCustomFilterDialog = True
        '
        If Me.AllowCreate Then
            GridView1.OptionsView.NewItemRowPosition = NewItemRowPosition.Top
        Else
            GridView1.OptionsView.NewItemRowPosition = NewItemRowPosition.None
        End If
        '
        If GridView1.DataRowCount > 1 Then
            GridView1.OptionsView.ShowAutoFilterRow = True
        Else
            GridView1.OptionsView.ShowAutoFilterRow = False
        End If

        GridView1.OptionsView.ShowChildrenInGroupPanel = True
        GridView1.OptionsView.ShowFilterPanelMode = Views.Base.ShowFilterPanelMode.ShowAlways

        'Necessaire pour les memoedit
        GridView1.OptionsView.RowAutoHeight = True

        'Le nom de l'onglet de la vue
        'GridView1.OptionsView.ShowViewCaption = True   'Permet d'afficher le nom du Caption dans une ligne en haut du Grid
        GridView1.ViewCaption = MetaDataTable.MetaCommand.Caption
        'Make sure that the columns are define in the view before assignning LOV'S
        DevExGridHelper.AssignLKP(CType(mainView, GridView), MetaDataTable, Me.GridControl1)
        tableColumns.Dispose()
        RaiseEvent AfterInitView(Me, GridView1)
    End Sub
    Private Sub GridView1_CellValueChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs) Handles GridView1.CellValueChanged
        If MasterCellValueChangedEvent IsNot Nothing Then
            RaiseEvent MasterCellValueChanged(sender, e)
        End If
    End Sub
    Private Sub GridView1_InitNewRow(ByVal sender As Object, ByVal e As InitNewRowEventArgs) Handles GridView1.InitNewRow
        If InitNewMasterRowEvent Is Nothing Then
            Dim view As GridView = CType(sender, GridView)
            view.SetRowCellValue(e.RowHandle, view.Columns(MetaDataTable.MetaCommand.GUIDField), System.Guid.NewGuid)
        Else
            RaiseEvent InitNewMasterRow(sender, e)
        End If
    End Sub

    Private Sub DetailView_CellValueChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs) Handles DetailView.CellValueChanged
        If DetailCellValueChangedEvent IsNot Nothing Then
            RaiseEvent DetailCellValueChanged(sender, e)
        End If
    End Sub
    Private Sub DetailView_InitNewRow(ByVal sender As Object, ByVal e As InitNewRowEventArgs) Handles DetailView.InitNewRow
        If InitNewDetailRowEvent Is Nothing Then
            Dim view As GridView = CType(sender, GridView)
            Dim drow As DataRow = view.GetFocusedDataRow()
            Dim table As MetaDataTable = CType(drow.Table, MetaDataTable)
            view.SetRowCellValue(e.RowHandle, view.Columns(table.MetaCommand.GUIDField), System.Guid.NewGuid)
        Else
            RaiseEvent InitNewDetailRow(sender, e)
        End If
    End Sub

    Public Function SaveCommand() As Boolean Implements CommonExt.ISaveCommand.SaveCommand
        Dim succesful As Boolean = True
        Dim expanded As Boolean
        Try
            Me.Cursor = Cursors.WaitCursor
            'On force la fermeture de l'éditeur.
            GridControl1.FocusedView.CloseEditor()
            GridControl1.FocusedView.UpdateCurrentRow()
            '
            Me.Refresh()
            'Capture Grid Layout

            If GridView1.GetMasterRowExpanded(GridView1.FocusedRowHandle) Then
                expanded = True
            End If

            'testPoint: SAVE to Database Start
            If Not Me.Dataset.HasErrors Then
                If Pl IsNot Nothing Then
                    succesful = Pl.Save()
                End If

                'Une fois sauver on avertie que le save a marcher
                If succesful Then
                    If expanded Then
                        GridView1.ExpandMasterRow(GridView1.FocusedRowHandle, DetailViewIndex)
                    End If
                    RaiseEvent AfterSave()
                End If
            Else
                succesful = False
            End If
        Catch ex As Exception
            If Not ex.InnerException Is Nothing AndAlso TypeOf (ex.InnerException) Is DBConcurrencyException Then
                MessageWindow.ShowMessage(ex.Message & "Try to reload and modify again.")
            Else
                MessageWindow.ShowMessage(ex.Message)
            End If
        Finally
            Me.Cursor = Cursors.Default
        End Try
        Return succesful
    End Function

    Private Sub GridView1_MasterRowExpanded(ByVal sender As Object, ByVal e As CustomMasterRowEventArgs) Handles GridView1.MasterRowExpanded
        DetailView = DirectCast(GridView1.GetDetailView(GridView1.FocusedRowHandle, e.RelationIndex), GridView)
        DetailViewIndex = e.RelationIndex
    End Sub
    '
    Private Sub GridView1_MasterRowExpanding(sender As Object, e As DevExpress.XtraGrid.Views.Grid.MasterRowCanExpandEventArgs) Handles GridView1.MasterRowExpanding
        'TODO: Pour se préparer a loader les enfants a la demande...
    End Sub

    Private Sub GridControl1_DragDrop(sender As Object, e As System.Windows.Forms.DragEventArgs) Handles GridControl1.DragDrop
        RaiseEvent DragDropExt(sender, e)
    End Sub


    Private Sub GridControl1_DragOver(sender As Object, e As System.Windows.Forms.DragEventArgs) Handles GridControl1.DragOver
        RaiseEvent DragOverExt(sender, e)
    End Sub


    Private Sub GridControl1_FocusedViewChanged(sender As Object, e As ViewFocusEventArgs) Handles GridControl1.FocusedViewChanged
        If Not IsNothing(e.View) Then ' this is required because of event is fired on form closing and View's are Nothing, at run time it raise an error.. why event is fired ... we don't know  -B.desjardins
            If DirectCast(e.View, DevExpress.XtraGrid.Views.Grid.GridView).IsDetailView Then
                DetailView = DirectCast(GridControl1.FocusedView, GridView)
            End If
        End If

        'Refactoring Child: 8- Prendre le DataSource de la DetailView et le passer au DirectCast(xx,MetaDataTable).FillBusinessApplicationData()
        'Exemple:
        'Dim mt As MetaDataTable
        'mt = TryCast(DetailView.DataSource, MetaDataTable)
        'If mt Is Nothing Then
        '    mt.FillBusinessApplicationData()
        'End If
    End Sub

    ''' <summary>
    ''' Delete the FocusedRow - Delete key
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>KeyUp does not raise when editing a Cell/Row</remarks>
    Private Sub GridControl1_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles GridControl1.KeyUp
        If e.KeyCode = Keys.Delete AndAlso Not e.Control Then
            DeleteCurrentRows()
        End If
    End Sub

    Private Sub GridControl1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles GridControl1.MouseClick
        Dim point As Point
        Dim hi As DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo

        If e.Button = MouseButtons.Right Then
            ' checking if the end-user has right clicked the grid control 
            point = New Point(e.X, e.Y)
            hi = CType(GridControl1.FocusedView.CalcHitInfo(point), Grid.ViewInfo.GridHitInfo)
            If hi.HitTest = Grid.ViewInfo.GridHitTest.RowIndicator Then
                If GridControl1.FocusedView.IsDetailView Then
                    If InitGridActionOptionListEvent IsNot Nothing Then
                        GridActionOptionList.Clear()
                        RaiseEvent InitGridActionOptionList(Me, e)
                    End If
                    DoShowDetailViewMenu(hi)

                Else
                    If InitGridActionOptionListEvent IsNot Nothing Then
                        GridActionOptionList.Clear()
                        RaiseEvent InitGridActionOptionList(Me, e)
                    End If
                    DoShowMainViewMenu(hi)

                End If
            End If
            End If
    End Sub
    Private Sub DoShowDetailViewMenu(ByVal hi As DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo)
        Dim item As DXMenuItem
        Dim dtlView As GridView = CType(GridControl1.FocusedView, GridView)
        Dim grpName As String = String.Empty
        Dim selectedRows As GridSelectedRows = New GridSelectedRows()

        GridContextMenu = New GridViewMenu(dtlView)
        AddHandler GridContextMenu.BeforePopup, AddressOf DetailViewContextMenu_BeforePopup

        If GridActionOptionList IsNot Nothing Then
            DefaultActionOptionList.ApplySecurity()
            For Each action As CommonExt.Base.ActionOption In DefaultActionOptionList
                item = New DXMenuItem(action.OptionTitle, action.EventHandler, Nothing)
                Select Case action.OptionName
                    Case "ZoomIn"
                        item.Enabled = GridControl1.FocusedView.IsDetailView And Not GridControl1.FocusedView.IsZoomedView
                    Case "ZoomOut"
                        item.Enabled = GridControl1.FocusedView.IsDetailView And GridControl1.FocusedView.IsZoomedView
                    Case Else
                        item.Enabled = True
                End Select
                'Add new Group Separator when Group Name change
                If (grpName <> action.OptionGroup And grpName <> String.Empty) Then
                    item.BeginGroup = True
                End If
                grpName = action.OptionGroup
                GridContextMenu.Items.Add(item)
            Next
            '
            GridActionOptionList.ApplySecurity()
            '
            'Add Action Option that need the grid DataRow
            For Each action As CommonExt.Base.ActionOption In Me.GridActionOptionList

                selectedRows.CurrentSelectedDataRow = dtlView.GetFocusedDataRow()
                selectedRows.ParentSelectedDataRow = ParentSelectedDataRow

                If Not action.WithHandler Then
                    item = New DXSubMenuItem(action.OptionTitle)
                Else
                    item = New DXMenuItem(action.OptionTitle, action.EventHandler, Nothing)
                End If

                'item.Tag = dtlView.GetFocusedDataRow()
                item.Tag = selectedRows

                item.Enabled = action.Enabled
                'item.Image = action.OptionIcon
                If item.Tag Is Nothing Then
                    item.Enabled = False
                End If

                'Add new Group Separator when Group Name change
                If (grpName <> action.OptionGroup And grpName <> String.Empty) Then
                    item.BeginGroup = True
                End If
                grpName = action.OptionGroup

                If String.IsNullOrEmpty(action.IndentLevelReference) OrElse action.IndentLevelReference = dtlView.Tag.ToString Then
                    If action.ParentActionOption Is Nothing Then
                        GridContextMenu.Items.Add(item)
                    Else
                        GetSubMenuItemIndex(action.ParentActionOption.OptionTitle, item)
                    End If
                End If
            Next
            'Display Menu
            GridContextMenu.Show(hi.HitPoint)
        End If
    End Sub
    Sub DoShowMainViewMenu(ByVal hi As DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo)
        Dim item As DXMenuItem = New DXMenuItem
        Dim grpName As String = String.Empty

        GridContextMenu = New GridViewMenu(GridView1)
        AddHandler GridContextMenu.BeforePopup, AddressOf MainViewContextMenu_BeforePopup
        If GridActionOptionList IsNot Nothing Then
            DefaultActionOptionList.ApplySecurity()
            For Each action As CommonExt.Base.ActionOption In DefaultActionOptionList

                item = New DXMenuItem(action.OptionTitle, action.EventHandler, Nothing)
                item.Enabled = action.Enabled
                '
                'OutStandingIssue: Des Event ca s'additionne - aleblanc 2012-05-07
                'AddHandler item.Click, AddressOf ContextMenuReloadGrid
                '
                'Add new Group Separator when Group Name change
                If (grpName <> action.OptionGroup And grpName <> String.Empty) Then
                    item.BeginGroup = True
                End If
                grpName = action.OptionGroup
                GridContextMenu.Items.Add(item)
            Next
            '
            GridActionOptionList.ApplySecurity()
            '
            'Add Action Option that need the grid DataRow
            For Each action As CommonExt.Base.ActionOption In Me.GridActionOptionList
                If Not action.WithHandler Then
                    item = New DXSubMenuItem(action.OptionTitle)
                Else
                    item = New DXMenuItem(action.OptionTitle, action.EventHandler, Nothing)
                End If
                item.Tag = GridView1.GetFocusedDataRow()

                'item.Visible = action.Visible
                item.Enabled = action.Enabled
                'item.Image = action.OptionIcon
                If item.Tag Is Nothing Then
                    item.Enabled = False
                End If
                'Add new Group Separator when Group Name change
                If (grpName <> action.OptionGroup And grpName <> String.Empty) Then
                    item.BeginGroup = True
                End If
                grpName = action.OptionGroup
                If String.IsNullOrEmpty(action.IndentLevelReference) OrElse action.IndentLevelReference = GridView1.Tag.ToString Then
                    If action.ParentActionOption Is Nothing Then
                        GridContextMenu.Items.Add(item)
                    Else
                        GetSubMenuItemIndex(action.ParentActionOption.OptionTitle, item)
                    End If
                End If
            Next


            '' Now we treat the menu with parent and handler
            'For Each action As CommonExt.Base.ActionOption In Me.GridActionOptionList
            '    If action.WithHandler AndAlso Not action.ParentActionOption Is Nothing Then
            '        'je sais que je dois trouver un item ds GridContextMenu qui as le title egale 
            '        'pis  faire un add.
            '        item = New DXMenuItem(action.OptionTitle, action.EventHandler, Nothing)


            '    End If
            'Next


            'Display Menu
            GridContextMenu.Show(hi.HitPoint)
        End If
    End Sub


    Public Function GetSubMenuItemIndex(ByVal title As String, ByVal actionItem As DXMenuItem) As Boolean

        For Each asubitem As DXMenuItem In GridContextMenu.Items
            If asubitem.Caption = title Then
                CType(asubitem, DXSubMenuItem).Items.Add(actionItem)
                Return True
            End If
        Next

        Return False

    End Function


    Private Sub GridExtPL_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        InitGridExt(LoadWithChilds)

        If AfterLoadEvent IsNot Nothing Then
            RaiseEvent AfterLoad(sender, e)
            If Me.AllowCreate Then
                GridView1.OptionsView.NewItemRowPosition = NewItemRowPosition.Top
                GridView1.OptionsEditForm.ShowOnDoubleClick = DevExpress.Utils.DefaultBoolean.False
                GridView1.OptionsEditForm.ShowOnEnterKey = DevExpress.Utils.DefaultBoolean.False
            Else
                GridView1.OptionsView.NewItemRowPosition = NewItemRowPosition.None
            End If
        End If
    End Sub
#Region " Context Action Menu"
    Private Sub InitActionOption()
        Dim act As CommonExt.Base.ActionOption
        GridActionOptionList = New CommonExt.Base.ActionOptionList()
        DefaultActionOptionList = New CommonExt.Base.ActionOptionList()

        'OutStandingIssue: Finir les renames de Sub Reload pour Refresh - aleblanc
        act = New CommonExt.Base.ActionOption("GridOption", "ACT_00167", "Refresh Data", AddressOf ContextMenuReloadGrid, True, True)
        DefaultActionOptionList.Add(act)

        act = New CommonExt.Base.ActionOption("GridOption", "ACT_00168", "Export to Excel", AddressOf ContextMenuExportToExcel, True, True)
        DefaultActionOptionList.Add(act)

        act = New CommonExt.Base.ActionOption("GridOption", "ACT_00171", "VEdit (From MainView Only)", AddressOf ContextMenuVEdit, True, True)
        DefaultActionOptionList.Add(act)

        act = New CommonExt.Base.ActionOption("GridOption", "ACT_00178", "Print", AddressOf ContextMenuPrint, True, True)
        DefaultActionOptionList.Add(act)

        act = New CommonExt.Base.ActionOption("DefaultOption", "ACT_00172", "Save", AddressOf ContextMenuSave, True, True)
        DefaultActionOptionList.Add(act)

        act = New CommonExt.Base.ActionOption("DefaultOption", "ACT_00173", "Delete", AddressOf ContextMenuDelete, True, True)
        DefaultActionOptionList.Add(act)

        act = New CommonExt.Base.ActionOption("DefaultOption2", "ACT_00174", "Restore to Default Layout", AddressOf ContextMenuRestoreDefaultLayout, True, True)
        DefaultActionOptionList.Add(act)

        act = New CommonExt.Base.ActionOption("DefaultOptionZ", "ACT_00175", "Zoom In", AddressOf ContextMenuZoomIn, False, True)
        DefaultActionOptionList.Add(act)
        act = New CommonExt.Base.ActionOption("DefaultOptionZ", "ACT_00176", "Zoom Out", AddressOf ContextMenuZoomOut, False, True)
        DefaultActionOptionList.Add(act)
    End Sub

    Private Sub ContextMenuPrint(ByVal sender As Object, ByVal e As EventArgs)
        Me.PrintGrid()
    End Sub

    Private Sub PrintGrid()
        If GridControl1.IsPrintingAvailable Then
            GridView1.AppearancePrint.Row.TextOptions.WordWrap = DevExpress.Utils.WordWrap.Wrap
            GridView1.OptionsPrint.AutoWidth = False
            GridView1.OptionsPrint.PrintDetails = True
            GridView1.OptionsPrint.ExpandAllDetails = True
            GridView1.OptionsPrint.ExpandAllGroups = True
            GridView1.ShowPrintPreview()
        End If
    End Sub

    Private Sub ContextMenuSave(ByVal sender As System.Object, ByVal e As EventArgs)
        Me.SaveCommand()
    End Sub
    Private Sub ContextMenuDelete(ByVal sender As System.Object, ByVal e As EventArgs)
        DeleteCurrentRows()
    End Sub
    Private Sub DeleteCurrentRows()
        Dim view As GridView = CType(Me.GridControl1.FocusedView, GridView)

        Dim okdelete As Boolean = Me.AllowDelete

        If view.IsDetailView Then
            If DetailAccess IsNot Nothing Then
                okdelete = DetailAccess.AllowDelete
            End If
        End If

        If okdelete Then
            If DeleteRowEvent Is Nothing Then
                view.DeleteSelectedRows()
            Else
                Dim cnclEvent As New CancelEventArgs(False)
                RaiseEvent DeleteRow(view.GetFocusedDataRow, cnclEvent)
                If Not cnclEvent.Cancel Then
                    view.DeleteSelectedRows()
                End If
            End If
        Else
            MessageWindow.ShowMessage("You do not have rights to delete row", MsgBoxStyle.Information)
        End If
    End Sub
    Private Sub ContextMenuVEdit(ByVal sender As System.Object, ByVal e As EventArgs)

        'Dim detailview As GridView = CType(Me.GridControl1.FocusedView, GridView)
        'Dim detailTable As MetaDataTable = CType(_aDataset.Tables(detailview.Tag.ToString), MetaDataTable)
        '_aVEdit = New VEdit
        '_aVEdit.Init(detailTable, detailview)
        ''HOWto: get the datatable rowindex from a Grid Devex

        'OutStandingIssue: Marche pas sur les child. Ne se positionne pas sur le bon record... aleblanc 2011-07-29

        '_aVEdit.ShowVEdit(detailview.GetDataSourceRowIndex(detailview.FocusedRowHandle))

        DoVedit()


        'If vEdit Is Nothing Then
        '    vEdit = New VEdit
        '    vEdit.Init(MetaDataTable, CType(GridControl1.MainView, GridView))
        'End If
        ''HOWto: get the datatable rowindex from a Grid Devex
        'vEdit.ShowVEdit(GridView1.GetDataSourceRowIndex(GridView1.FocusedRowHandle))
    End Sub

    Public Sub DoVedit()
        If vEdit Is Nothing Then
            vEdit = New VEdit
            vEdit.Init(MetaDataTable, CType(GridControl1.MainView, GridView))
        End If
        'HOWto: get the datatable rowindex from a Grid Devex
        vEdit.ShowVEdit(GridView1.GetDataSourceRowIndex(GridView1.FocusedRowHandle))
    End Sub



    Private Sub ContextMenuExportToExcel(ByVal sender As System.Object, ByVal e As EventArgs)
        'OutStandingIssue: On ne peut pas exporter la vue detail seulement... Il faut passerpar la Vue principal.
        'Work Around: Reconstruire une grille avec la table dataSet via le FocusedView.Tag.ToString (Comme ContextMenuVEdit) et appliquer un filtre apartir du la Row Parent.
        'aleblanc - 2011-07-26
        'http://www.devexpress.com/Support/Center/p/S130097.aspx.  C'est pareil pour les XLS
        '
        Dim filename As String
        Try
            'filename = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), GridView1.Tag.ToString + ".xls")
            filename = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), GridView1.Tag.ToString)
            Using aFile As New System.Windows.Forms.SaveFileDialog
                aFile.DefaultExt = "xls"
                aFile.FileName = filename
                aFile.AutoUpgradeEnabled = True
                If aFile.ShowDialog() = DialogResult.OK Then

                    GridView1.OptionsPrint.AutoWidth = False
                    GridView1.OptionsPrint.PrintDetails = True
                    GridView1.OptionsPrint.ExpandAllDetails = True
                    GridView1.OptionsPrint.ExpandAllGroups = True
                    GridView1.ExportToXls(aFile.FileName)

                    MessageWindow.ShowMessage(String.Format("Export To Excel Succesfull.{0}{0}Your Filename is: {1}", vbCrLf, aFile.FileName), MsgBoxStyle.Information)

                End If
            End Using
        Catch ex As Exception
            Throw ex
        End Try
        Me.Cursor = Cursors.Default
    End Sub
    Private Sub ContextMenuReloadGrid(ByVal sender As System.Object, ByVal e As EventArgs)
        ReloadGrid()
    End Sub
    Private Sub ContextMenuRestoreDefaultLayout(ByVal sender As System.Object, ByVal e As EventArgs)
        Dim aView As GridView = DirectCast(GridControl1.FocusedView, GridView)
        Dim sqlcmd As System.Data.SqlClient.SqlCommand = Nothing
        Dim aDataView As DataView = CType(aView.DataSource, DataView)

        Try
            sqlcmd = MetaQuery.GetSPCmdByMetaName("SSPMetaUserColumnRemoveCustomization")
            sqlcmd.Parameters("@UserID").Value = AppManager.UserID
            sqlcmd.Parameters("@QueryName").Value = aDataView.Table.TableName

            sqlcmd.ExecuteNonQuery()

        Catch sqlex As System.Data.SqlClient.SqlException
            Throw sqlex
        Finally
            If sqlcmd IsNot Nothing Then
                sqlcmd.Connection.Close()
                sqlcmd.Dispose()
            End If
        End Try

        MessageWindow.ShowMessage("Restore to Default Layout Successful", MsgBoxStyle.Information)
        Me.Cursor = Cursors.Default
    End Sub
#End Region
    Public Sub ReloadGrid()
        Dim aGuid As Guid? = Nothing
        Dim aDataRow As DataRow

        'OutstandingIssue: On va devoir "peut-être" tenir compte des Group pour se repositionner sur la bonne ligne quand on a des Group BY
        ' aleblanc - 2012-05-17

        Dim aRowIndex As Integer
        'Est utiliser pour essayer de rester dans la meme page de la grille. Si on garde pas la premiere ligne 
        '
        Dim aTopRowIndex As Integer

        Me.Cursor = Cursors.WaitCursor
        GridControl1.BeginUpdate()
        If GridView1.FocusedRowHandle >= 0 Then
            aTopRowIndex = GridView1.TopRowIndex
            aDataRow = GridView1.GetFocusedDataRow()
            If Not String.IsNullOrEmpty(Me.MetaDataTable.GUIDField) Then
                aGuid = CType(aDataRow(Me.MetaDataTable.GUIDField), Guid)
            End If
        End If

        GridControl1.DataSource = Nothing
        '
        'On enleve les LOV de la grilles
        'Car pour les LOV on réutilise les colonnes qui on déjà le même LOV
        Dim aLOV As RepositoryItem
        For i As Integer = GridControl1.RepositoryItems.Count - 1 To 0 Step -1
            aLOV = GridControl1.RepositoryItems(i)
            'by design, nos LOV, le nom est le GUID de la Metaquery
            If Guid.TryParse(aLOV.Name, Nothing) Then
                GridControl1.RepositoryItems.RemoveAt(i)
            End If
        Next
        '
        InitGridExt(LoadWithChilds)
        If aGuid IsNot Nothing Then
            aRowIndex = GridView1.LocateByValue(0, GridView1.Columns(Me.MetaDataTable.GUIDField), aGuid, Nothing)
            If aRowIndex >= 0 Then
                If GridView1.TopRowIndex < aRowIndex Then
                    GridView1.TopRowIndex = aTopRowIndex
                End If
                GridView1.MoveBy(aRowIndex)
                GridView1.SelectRow(aRowIndex)
            End If
        End If
        '
        GridControl1.EndUpdate()
        Me.Cursor = Cursors.Default
    End Sub
    Private Sub ContextMenuZoomIn(ByVal sender As System.Object, ByVal e As EventArgs)
        GridControl1.FocusedView.ZoomView()
    End Sub
    Private Sub ContextMenuZoomOut(ByVal sender As System.Object, ByVal e As EventArgs)
        GridControl1.FocusedView.NormalView()
    End Sub

    Private Sub DetailView_ShownEditor(sender As Object, e As System.EventArgs) Handles DetailView.ShownEditor
        'Dim view As GridView = TryCast(sender, GridView)
        'If view.FocusedRowHandle = GridControl.NewItemRowHandle Then
        '    view.DataController.AddNewRow()
        'End If
        RaiseEvent ShownDetailEditor(sender, e)
    End Sub
    Private Sub GridView1_ShownEditor(sender As Object, e As System.EventArgs) Handles GridView1.ShownEditor
        'Dim view As GridView = TryCast(sender, GridView)
        'If view.FocusedRowHandle = GridControl.NewItemRowHandle Then
        '    view.DataController.AddNewRow()
        'End If
        RaiseEvent ShownMasterEditor(sender, e)
    End Sub
    Private Sub DetailView_HiddenEditor(sender As Object, e As System.EventArgs) Handles DetailView.HiddenEditor
        RaiseEvent HiddenDetailEditor(sender, e)
    End Sub
    Private Sub GridView1_HiddenEditor(sender As Object, e As System.EventArgs) Handles GridView1.HiddenEditor
        RaiseEvent HiddenMasterEditor(sender, e)
    End Sub
    Private Sub GridView1_InvalidRowException(sender As Object, e As DevExpress.XtraGrid.Views.Base.InvalidRowExceptionEventArgs) Handles GridView1.InvalidRowException
        e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction
    End Sub
    Private Sub GridView1_ValidateRow(ByVal sender As System.Object, ByVal e As DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs) Handles GridView1.ValidateRow
        ' AL - 2011-09-16
        ' C'est dans le bonne ordre, choix de design.
        ' ProcessCurrentDetailRecord peux générer des valeur qui vont être valider par la suite
        Dim row As DataRow
        If e.Row IsNot Nothing Then
            row = CType(e.Row, DataRowView).Row
            If ValidateMasterRowEvent IsNot Nothing Then
                RaiseEvent ProcessCurrentMasterRecord(sender, e)
                RaiseEvent ValidateMasterRow(sender, e)
            Else
                'Permet d'avoir un validateRow dans le PL sans avoir de Addhandler ValidateMasterRow - AL - 2011-11-23
                RaiseEvent ProcessCurrentMasterRecord(sender, e)
                Pl.ValidateRow(row)
            End If
            If row.HasErrors Then
                e.Valid = False
            End If
        End If
    End Sub
    Private Sub detailView_InvalidRowException(sender As Object, e As DevExpress.XtraGrid.Views.Base.InvalidRowExceptionEventArgs) Handles DetailView.InvalidRowException
        e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction
    End Sub
    Private Sub detailView_ValidateRow(sender As Object, e As DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs) Handles DetailView.ValidateRow
        ' AL - 2011-09-16
        ' C'est dans le bonne ordre, choix de design.
        ' ProcessCurrentDetailRecord peux générer des valeur qui vont être valider par la suite
        Dim row As DataRow
        If e.Row IsNot Nothing Then
            row = CType(e.Row, DataRowView).Row
            RaiseEvent ProcessCurrentDetailRecord(sender, e, DetailViewIndex)
            RaiseEvent ValidateDetailRow(sender, e)
            If row.HasErrors Then
                e.Valid = False
            End If
        End If
    End Sub
    Private Sub GridView1_RowCellStyle(sender As Object, e As DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs) Handles GridView1.RowCellStyle
        If MasterRowCellStyleEvent IsNot Nothing Then
            RaiseEvent MasterRowCellStyle(sender, e)
        End If
    End Sub
    Private Sub DetailView_RowCellStyle(sender As Object, e As DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs) Handles DetailView.RowCellStyle
        If DetailRowCellStyleEvent IsNot Nothing Then
            RaiseEvent DetailRowCellStyle(sender, e)
        End If
    End Sub
    Private Sub GridView1_CustomColumnDisplayText(sender As Object, e As DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs) Handles GridView1.CustomColumnDisplayText
        If MasterCustomColumnDisplayTextEvent IsNot Nothing Then
            RaiseEvent MasterCustomColumnDisplayText(sender, e)
        End If
    End Sub
    Private Sub DetailView_CustomColumnDisplayText(sender As Object, e As DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs) Handles DetailView.CustomColumnDisplayText
        If DetailCustomColumnDisplayTextEvent IsNot Nothing Then
            RaiseEvent DetailCustomColumnDisplayText(sender, e)
        End If
    End Sub
    Private Sub DetailView_FocusedRowChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs) Handles DetailView.FocusedRowChanged
        Dim datarow As DataRow = DetailView.GetDataRow(e.PrevFocusedRowHandle)
        If datarow IsNot Nothing AndAlso datarow.HasErrors Then
            datarow.ClearErrors()
        End If
    End Sub
    Private Sub GridView1_FocusedRowChanged(sender As Object, e As DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs) Handles GridView1.FocusedRowChanged
        Dim datarow As DataRow = GridView1.GetDataRow(e.PrevFocusedRowHandle)
        If datarow IsNot Nothing AndAlso datarow.HasErrors Then
            datarow.ClearErrors()
        End If
    End Sub

    Private Sub DetailView_RowStyle(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs) Handles DetailView.RowStyle
        DevExGridHelper.AssignSearchAndAddRowProperty(e)
        If DetailRowStyleEvent IsNot Nothing Then
            RaiseEvent DetailRowStyle(sender, e)
        End If
    End Sub
    Private Sub GridView1_RowStyle(sender As Object, e As DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs) Handles GridView1.RowStyle
        DevExGridHelper.AssignSearchAndAddRowProperty(e)
        If MasterRowStyleEvent IsNot Nothing Then
            RaiseEvent MasterRowStyle(sender, e)
        End If
    End Sub
    Private Sub DetailView_CustomRowCellEditForEditing(sender As Object, e As DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs) Handles DetailView.CustomRowCellEditForEditing
        If DetailCustomRowCellEditForEditingEvent IsNot Nothing Then
            RaiseEvent DetailCustomRowCellEditForEditing(sender, e)
        Else
            Dim aView As GridView = DirectCast(sender, GridView)
            Dim aMt As MetaDataTable = DirectCast(DirectCast(aView.DataSource, DataView).Table, MetaDataTable)
            Dim aLOV As RepositoryItemGridLookUpEdit = Nothing
            aLOV = DevExGridHelper.BuildLOV(aView, aMt, Me.GridControl1, e.Column.FieldName)
            If aLOV IsNot Nothing Then
                e.RepositoryItem = aLOV
            End If
        End If
    End Sub
    Private Sub GridView1_CustomRowCellEditForEditing(sender As Object, e As DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs) Handles GridView1.CustomRowCellEditForEditing
        If MasterCustomRowCellEditForEditingEvent IsNot Nothing Then
            RaiseEvent MasterCustomRowCellEditForEditing(sender, e)
        Else
            Dim aView As GridView = DirectCast(sender, GridView)
            Dim aMt As MetaDataTable = DirectCast(DirectCast(aView.DataSource, DataView).Table, MetaDataTable)
            Dim aLOV As RepositoryItemGridLookUpEdit = Nothing
            aLOV = DevExGridHelper.BuildLOV(aView, aMt, Me.GridControl1, e.Column.FieldName)
            If aLOV IsNot Nothing Then
                e.RepositoryItem = aLOV
            End If
        End If
    End Sub

    ''' <summary>
    ''' Used to set the look of the grid like a listBox 
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub SetListlike()
        'GridControl1
        '
        Me.GridControl1.UseEmbeddedNavigator = False
        '
        'GridView1
        '
        Me.GridView1.HorzScrollVisibility = DevExpress.XtraGrid.Views.Base.ScrollVisibility.Always
        Me.GridView1.Name = "GridView1"
        Me.GridView1.OptionsDetail.AllowExpandEmptyDetails = True
        Me.GridView1.OptionsDetail.AllowOnlyOneMasterRowExpanded = True
        Me.GridView1.OptionsDetail.EnableDetailToolTip = True
        Me.GridView1.OptionsFilter.DefaultFilterEditorView = DevExpress.XtraEditors.FilterEditorViewMode.VisualAndText
        Me.GridView1.OptionsFilter.ShowAllTableValuesInFilterPopup = True
        Me.GridView1.OptionsFilter.UseNewCustomFilterDialog = False
        Me.GridView1.OptionsFilter.AllowFilterEditor = False
        Me.GridView1.OptionsView.ShowGroupPanel = False
        Me.GridView1.OptionsSelection.MultiSelect = False
        Me.GridView1.OptionsView.ShowAutoFilterRow = True
        Me.GridView1.OptionsView.ShowChildrenInGroupPanel = True
        Me.GridView1.OptionsView.ShowFilterPanelMode = DevExpress.XtraGrid.Views.Base.ShowFilterPanelMode.Never
        Me.GridView1.OptionsView.ShowIndicator = False
        Me.GridView1.OptionsBehavior.AllowAddRows = DevExpress.Utils.DefaultBoolean.False
        Me.GridView1.OptionsView.NewItemRowPosition = NewItemRowPosition.None
    End Sub


    Private Sub GridView1_RowClick(sender As Object, e As DevExpress.XtraGrid.Views.Grid.RowClickEventArgs) Handles GridView1.RowClick
        If MasterRowClickEvent IsNot Nothing Then
            RaiseEvent MasterRowClick(sender, e)
        End If
    End Sub
    Private Sub DetailView_RowClick(sender As Object, e As DevExpress.XtraGrid.Views.Grid.RowClickEventArgs) Handles DetailView.RowClick
        If DetailRowClickEvent IsNot Nothing Then
            RaiseEvent DetailRowClick(sender, e)
        End If
    End Sub

    ''' <summary>
    ''' Shortcut key to:
    ''' CTRL-ALT-E = Export the Metaquery of the focus View
    ''' CTRL-ALT-Q = Display MetaQuery
    ''' CTRL-ALT-S = AutoSize the focus View
    ''' CTRL-ALT-L = SaveLayout of the focus View
    ''' CTRL-ALT-G = GetLayout of the focus View
    ''' CTRL-SHFT-L = SaveLayout of the focus view in DataBase
    ''' CTRL-S = Save Change
    ''' CTRL-R or F5 = Reload the grid without Saving
    ''' CTRL-ALT-A = Display Allow... and optionbehevior 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>GridControl Always Raise whatever the view or mode we are (View vs Editing)</remarks>
    Private Sub GridControl1_ProcessGridKey(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles GridControl1.ProcessGridKey
        Dim message As String
        Dim view As GridView = TryCast(GridControl1.FocusedView, GridView)
        '
        If (e.Control AndAlso e.KeyCode = Keys.R) Or e.KeyCode = Keys.F5 Then
            Me.Reload()
            e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
        End If

        '   to be used on EditForm.
        If (e.Control AndAlso e.KeyCode = Keys.R) Or e.KeyCode = Keys.F2 Then
            GridView1.OptionsBehavior.EditingMode = GridEditingMode.EditForm
            GridView1.ShowPopupEditForm()

            e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
        End If

        If view IsNot Nothing Then

            If e.Control AndAlso e.KeyCode = Keys.P Then
                Me.PrintGrid()
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
            End If

            If e.Control AndAlso e.Alt AndAlso e.KeyCode = Keys.Q AndAlso view.Tag IsNot Nothing Then
                message = String.Concat("MetaQuery: ", view.Tag.ToString, vbCrLf)
                MessageWindow.ShowMessage(message, MsgBoxStyle.Information)
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
            End If

            If e.Control AndAlso e.Alt AndAlso e.KeyCode = Keys.A AndAlso view.Tag IsNot Nothing Then
                Dim ListString As Generic.List(Of String) = New List(Of String)
                ListString.Add(String.Format("AllowCreate : {0} ,{1}", Me.AllowCreate, vbCrLf))
                ListString.Add(String.Format("AllowRead : {0} ,{1}", Me.AllowRead, vbCrLf))
                ListString.Add(String.Format("AllowUpdate : {0} ,{1}", Me.AllowUpdate, vbCrLf))
                ListString.Add(String.Format("AllowDelete : {0} ,{1}", Me.AllowDelete, vbCrLf))
                ListString.Add(String.Format("Readonly : {0} ,{1}", Me.GridView1.OptionsBehavior.ReadOnly, vbCrLf))
                For Each acolumn As GridColumn In Me.GridView1.Columns
                    ListString.Add(String.Format("column : {0} , ReadOnly : {1}, {2}", acolumn.Name, acolumn.OptionsColumn.ReadOnly, vbCrLf))
                Next
                message = ""
                For Each astring In ListString
                    message = String.Concat(message, astring)
                Next
                MessageWindow.ShowMessage(message, MsgBoxStyle.Information)
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
            End If


            If e.Control AndAlso e.Alt AndAlso e.KeyCode = Keys.S Then
                BestFitColumn(view)
                e.Handled = True
            ElseIf e.Control AndAlso e.KeyCode = Keys.S Then
                Me.SaveCommand()
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
            End If

            'Export MetaCommand
            If e.Control AndAlso e.Alt AndAlso e.KeyCode = Keys.E AndAlso view.Tag IsNot Nothing Then
                Using mq As MetaQuery = MetaQuery.GetMetaQueryByName(view.Tag.ToString)
                    Using aFile As New System.Windows.Forms.SaveFileDialog
                        aFile.DefaultExt = "xml"
                        aFile.FileName = String.Format("MetaQuery_{0}", mq.QueryName)
                        aFile.AutoUpgradeEnabled = True
                        If aFile.ShowDialog() = DialogResult.OK Then
                            If SystemBoxSDK.PL.MetaSDK.MetaCommand_PL.ExportMetaCommand(aFile.FileName, mq.QueryID) Then
                                MessageWindow.ShowMessage("Export Command Successful", MsgBoxStyle.Information)
                            End If
                        End If
                    End Using
                End Using
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
            End If

            'Save Layout of the Focus  (XML file on computer)
            If e.Control AndAlso e.Alt AndAlso e.KeyCode = Keys.L AndAlso view.Tag IsNot Nothing Then
                Using aFile As New System.Windows.Forms.SaveFileDialog
                    aFile.DefaultExt = "xml"
                    aFile.FileName = String.Format("GridExtLayout_{0}", view.Tag)
                    aFile.AutoUpgradeEnabled = True
                    If aFile.ShowDialog() = DialogResult.OK Then
                        view.SaveLayoutToXml(aFile.FileName)
                        MessageWindow.ShowMessage("Save Layout Successful", MsgBoxStyle.Information)
                    End If
                End Using
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
            End If

            'Load Layout For the Focus View (from XML file on computer)
            If e.Control AndAlso e.Alt AndAlso e.KeyCode = Keys.G AndAlso view.Tag IsNot Nothing Then
                Using aFile As New System.Windows.Forms.OpenFileDialog
                    aFile.DefaultExt = "xml"
                    aFile.FileName = String.Format("GridExtLayout_{0}.xml", view.Tag)
                    aFile.AutoUpgradeEnabled = True
                    If aFile.ShowDialog() = DialogResult.OK Then
                        view.RestoreLayoutFromXml(aFile.FileName)
                    End If
                End Using
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
            End If

            'Save Layout of the Focus View (in database)
            If e.Control AndAlso e.Shift AndAlso e.KeyCode = Keys.L Then
                Me.Cursor = Cursors.WaitCursor
                For Each col As GridColumn In view.Columns
                    Dim sqlcmd As System.Data.SqlClient.SqlCommand = Nothing
                    Dim aDataView As DataView = CType(view.DataSource, DataView)

                    Try
                        sqlcmd = MetaQuery.GetSPCmdByMetaName("SSPMetaUserColumnSaveCustomization")
                        sqlcmd.Parameters("@QueryName").Value = aDataView.Table.TableName
                        sqlcmd.Parameters("@ColumnName").Value = col.FieldName
                        sqlcmd.Parameters("@UserID").Value = AppManager.UserID

                        If col.GroupIndex < 0 Then
                            sqlcmd.Parameters("@pOrder").Value = col.VisibleIndex
                        Else
                            sqlcmd.Parameters("@pOrder").Value = view.VisibleColumns.Count + col.GroupIndex
                        End If

                        sqlcmd.Parameters("@pVisible").Value = col.Visible
                        sqlcmd.Parameters("@pWidth").Value = col.Width
                        sqlcmd.Parameters("@pLocked").Value = col.OptionsColumn.ReadOnly
                        sqlcmd.Parameters("@pGroupByOrder").Value = col.GroupIndex
                        sqlcmd.Parameters("@pSortByOrder").Value = col.SortIndex

                        Select Case col.SortOrder
                            Case DevExpress.Data.ColumnSortOrder.Ascending
                                sqlcmd.Parameters("@pSortOrderID_FK").Value = IdRepository.APP_COLUMNSORTORDER_ASCENDING
                            Case DevExpress.Data.ColumnSortOrder.Descending
                                sqlcmd.Parameters("@pSortOrderID_FK").Value = IdRepository.APP_COLUMNSORTORDER_DESCENDING
                            Case Else
                                sqlcmd.Parameters("@pSortOrderID_FK").Value = IdRepository.APP_COLUMNSORTORDER_NONE
                        End Select
                        '
                        sqlcmd.ExecuteNonQuery()
                        '
                    Catch sqlex As System.Data.SqlClient.SqlException
                        Throw sqlex
                    Finally
                        If sqlcmd IsNot Nothing Then
                            sqlcmd.Connection.Close()
                            sqlcmd.Dispose()
                        End If
                    End Try
                Next
                MessageWindow.ShowMessage("Save Layout to your Profile Successful", MsgBoxStyle.Information)
                e.Handled = True 'TestPoint: Si on le met pas on peut passer 2 ou 3 fois selon le nombre de touche. aleblanc
                Me.Cursor = Cursors.Default
            End If
        End If
        'Fonctionne avec les query qui on un champ pOrder
        If e.Control AndAlso e.KeyCode = Keys.Subtract Then
            MoveRowUp(CType(sender, GridControl))
        End If

        If e.Control AndAlso e.KeyCode = Keys.Add Then
            MoveRowDown(CType(sender, GridControl))
        End If

        RaiseEvent AfterProcessGridKey(sender, e)
    End Sub


    ''' <summary>
    ''' Ajust to bestfitcolumn except Column larger than 800.
    ''' </summary>
    ''' <param name="view"></param>
    ''' <remarks></remarks>
    Private Sub BestFitColumn(ByVal view As GridView)
        Dim width As Integer
        GridControl1.BeginUpdate()
        For Each col As DevExpress.XtraGrid.Columns.GridColumn In view.Columns
            width = view.CalcColumnBestWidth(col)
            If width > 800 Then
                width = col.Width 'Put back value we have in MetaColumns Definition
            End If
            col.Width = width
        Next
        GridControl1.EndUpdate()
    End Sub

    Private Sub MoveRowUp(ByVal gridcontrol As GridControl)
        Dim view As GridView = DirectCast(gridcontrol.FocusedView, GridView)

        view.GridControl.Focus()
        Dim index As Integer = view.FocusedRowHandle
        If index <= 0 Then
            Return
        End If

        Dim row1 As DataRow = view.GetDataRow(index)
        Dim row2 As DataRow = view.GetDataRow(index - 1)
        If row1.Table.Columns.Contains("pOrder") Then

            Dim val1 As Object = row1("pOrder")
            Dim val2 As Object = row2("pOrder")
            row1("pOrder") = val2
            row2("pOrder") = val1

            view.FocusedRowHandle = index - 1
        End If
    End Sub

    Private Sub MoveRowDown(ByVal gridcontrol As GridControl)
        Dim view As GridView = DirectCast(gridcontrol.FocusedView, GridView)
        view.GridControl.Focus()
        Dim index As Integer = view.FocusedRowHandle
        If index >= view.DataRowCount - 1 Then
            Return
        End If

        Dim row1 As DataRow = view.GetDataRow(index)
        Dim row2 As DataRow = view.GetDataRow(index + 1)

        If row1.Table.Columns.Contains("pOrder") Then
            Dim val1 As Object = row1("pOrder")
            Dim val2 As Object = row2("pOrder")
            row1("pOrder") = val2
            row2("pOrder") = val1
            view.FocusedRowHandle = index + 1
        End If
    End Sub


    Private Sub GridControl1_ViewRegistered(sender As Object, e As DevExpress.XtraGrid.ViewOperationEventArgs) Handles GridControl1.ViewRegistered
        If Not String.IsNullOrWhiteSpace(FormCtrlCD) Then
            Dim view As GridView
            Dim mqCtrlName As String = Nothing
            '
            view = CType(e.View, GridView)
            CType(view.DataSource, DataView).AllowNew = False
            CType(view.DataSource, DataView).AllowDelete = False
            CType(view.DataSource, DataView).AllowEdit = False
            mqCtrlName = AppManager.GetControlMqFromForm(FormCtrlCD, view.Tag.ToString)
            If Not String.IsNullOrWhiteSpace(mqCtrlName) Then
                DetailAccess = New MetaQueryAccess(mqCtrlName)
                CType(view.DataSource, DataView).AllowNew = DetailAccess.AllowCreate
                CType(view.DataSource, DataView).AllowDelete = DetailAccess.AllowDelete
                CType(view.DataSource, DataView).AllowEdit = DetailAccess.AllowUpdate

                If Not CType(view.DataSource, DataView).AllowNew Then
                    view.OptionsView.NewItemRowPosition = NewItemRowPosition.None
                End If
            End If
        End If
        If AfterViewRegisteredEvent IsNot Nothing Then
            RaiseEvent AfterViewRegistered(sender, e)
        End If
    End Sub

    Private Sub DetailViewContextMenu_BeforePopup(ByVal sender As Object, ByVal e As EventArgs)
        If DetailContextMenuBeforePopupEvent IsNot Nothing Then
            RaiseEvent DetailContextMenuBeforePopup(sender, e)
        End If
    End Sub



    Private Sub MainViewContextMenu_BeforePopup(ByVal sender As Object, ByVal e As EventArgs)
        If MainContextMenuBeforePopupEvent IsNot Nothing Then
            RaiseEvent MainContextMenuBeforePopup(sender, e)
        End If
    End Sub

    Public Sub Reload() Implements CommonExt.IReloadCommand.ReloadCommand
        ReloadGrid()
    End Sub
    ''' <summary>
    ''' Create a new row Parent Row
    ''' </summary>
    ''' <remarks>Use Interface INewCommand, So we can call it from the Ribbon button New</remarks>
    Public Sub NewCommand() Implements CommonExt.INewCommand.NewCommand
        If Me.AllowCreate Then
            GridView1.AddNewRow()
        Else
            MessageWindow.ShowMessage("You do not have rights to add new row", MsgBoxStyle.Information)
        End If
    End Sub

    Private Sub DetailView_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles DetailView.MouseMove
        RaiseEvent DetailMouseMove(sender, e)
    End Sub

    Private Sub DetailView_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles DetailView.MouseDown
        RaiseEvent DetailMouseDown(sender, e)
    End Sub

    Private Sub GridView1_RowUpdated(sender As Object, e As DevExpress.XtraGrid.Views.Base.RowObjectEventArgs) Handles GridView1.RowUpdated
        If MasterRowNotifyEvent IsNot Nothing Then
            RaiseEvent MasterRowNotify(sender, e)
        End If
    End Sub
    Private Sub DetailView_RowUpdated(sender As Object, e As DevExpress.XtraGrid.Views.Base.RowObjectEventArgs) Handles DetailView.RowUpdated
        If DetailRowNotifyEvent IsNot Nothing Then
            RaiseEvent DetailRowNotify(sender, e)
        End If
    End Sub
End Class

Public Class VEdit
    Inherits VEditFormExt

    Private WithEvents _metaDataTable As CommonExt.MetaDataTable
    Private vGrid As DevExpress.XtraVerticalGrid.VGridControl
    Public Sub New()
        MyBase.New()
    End Sub
    Public Sub Init(ByVal dataTable As CommonExt.MetaDataTable, ByVal gridView As GridView)
        Dim View As Views.Base.ColumnView = gridView
        _metaDataTable = dataTable
        vGrid = Me.VGridExt1.VGridControl1
        vGrid.DataSource = _metaDataTable.Copy
        vGrid.RetrieveFields()
        vGrid.OptionsBehavior.AutoFocusNewRecord = True
        For Each arow As BaseRow In vGrid.Rows
            'by default VerticalGrid devexpress add the prefix 'row' to the fieldname when RetrieveField method is used.
            Dim aRowName As String = arow.Name.Remove(0, 3)
            'outStanding : memory leak verification should be performed by 2011-08-15 B.Desjardins
            arow.Properties.RowEdit = View.Columns(aRowName).ColumnEdit()
            arow.Properties.Caption = View.Columns(aRowName).Caption
            arow.Properties.ReadOnly = View.Columns(aRowName).ReadOnly
            arow.Visible = View.Columns(aRowName).Visible
            arow.Appearance.Options.UseTextOptions = True
            arow.Appearance.TextOptions.WordWrap = DevExpress.Utils.WordWrap.Wrap
            arow.Appearance.TextOptions.Trimming = DevExpress.Utils.Trimming.None
        Next

    End Sub
    Public Sub intLOV()

    End Sub


    Public Function ShowVEdit(ByVal aRecordIndex As Integer) As Boolean
        If aRecordIndex < 0 Then
            vGrid.AddNewRecord()

        Else
            vGrid.FocusedRecord = aRecordIndex
        End If

        Return Me.ShowDialog() = System.Windows.Forms.DialogResult.OK
    End Function



End Class


